import requests
import json
import time
from datetime import datetime
from tenacity import retry, stop_after_attempt, wait_exponential


class DeviceConnector:
    """设备连接器 - 负责与阿里云设备通信"""
    
    def __init__(self, device_config):
        self.config = device_config
        self.name = device_config.get('name', 'Unknown Device')
        self.url = device_config.get('url')
        self.token = device_config.get('token')
        self.timeout = device_config.get('timeout', 3)
        
    @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10))
    def fetch_data(self):
        """获取设备原始数据 - 带重试机制"""
        try:
            headers = {
                'Authorization': f'Bearer {self.token}',
                'Content-Type': 'application/json'
            }
            
            print(f"[{datetime.now()}] 正在获取 {self.name} 数据...")
            
            response = requests.get(
                self.url,
                headers=headers,
                timeout=self.timeout
            )
            
            if response.status_code == 200:
                data = response.json()
                print(f"[{datetime.now()}] {self.name} 数据获取成功")
                return data
            else:
                print(f"[{datetime.now()}] {self.name} 返回错误状态码: {response.status_code}")
                return None
                
        except requests.exceptions.Timeout:
            print(f"[{datetime.now()}] {self.name} 连接超时")
            return None
        except requests.exceptions.ConnectionError:
            print(f"[{datetime.now()}] {self.name} 连接失败")
            return None
        except Exception as e:
            print(f"[{datetime.now()}] {self.name} 发生错误: {str(e)}")
            return None
    
    def send_command(self, command):
        """发送控制指令到设备"""
        try:
            headers = {
                'Authorization': f'Bearer {self.token}',
                'Content-Type': 'application/json'
            }
            
            payload = {'command': command}
            
            response = requests.post(
                f"{self.url}/control",
                headers=headers,
                json=payload,
                timeout=self.timeout
            )
            
            if response.status_code == 200:
                print(f"[{datetime.now()}] {self.name} 指令发送成功: {command}")
                return response.json()
            else:
                print(f"[{datetime.now()}] {self.name} 指令发送失败: {response.status_code}")
                return None
                
        except Exception as e:
            print(f"[{datetime.now()}] {self.name} 指令发送错误: {str(e)}")
            return None


class MockDeviceConnector(DeviceConnector):
    """模拟设备连接器 - 用于开发测试"""
    
    def __init__(self, device_config):
        super().__init__(device_config)
        self.mock_data_counter = 0
        
    def fetch_data(self):
        """返回模拟数据"""
        import random
        
        self.mock_data_counter += 1
        
        # 模拟心率和呼吸数据的自然波动
        base_heart_rate = 72
        base_breath_rate = 16
        
        mock_data = {
            'device_id': self.config.get('name', 'mock_device'),
            'timestamp': datetime.now().isoformat(),
            'heart_rate': base_heart_rate + random.randint(-5, 8),
            'breath_rate': base_breath_rate + random.randint(-2, 3),
            'temperature': round(36.5 + random.uniform(-0.5, 0.8), 1),
            'humidity': random.randint(45, 65),
            'servoangle': random.randint(0, 45),
            'pose': random.choice(['flat', 'raised', 'side']),
            'sleep_stage': random.choice(['awake', 'light', 'deep', 'rem']),
            'data_quality': random.choice(['good', 'fair', 'poor']),
            'counter': self.mock_data_counter
        }
        
        print(f"[{datetime.now()}] {self.name} 模拟数据生成: 心率{mock_data['heart_rate']}, 呼吸{mock_data['breath_rate']}")
        
        # 模拟偶尔的网络延迟
        if random.random() < 0.1:
            time.sleep(0.5)
            
        return mock_data
    
    def send_command(self, command):
        """模拟发送指令"""
        print(f"[{datetime.now()}] {self.name} 模拟指令执行: {command}")
        return {'status': 'success', 'command': command, 'result': '指令已执行'}


if __name__ == "__main__":
    # 测试设备连接器
    mock_config = {
        'name': '测试设备',
        'url': 'mock://test',
        'token': 'test_token'
    }
    
    connector = MockDeviceConnector(mock_config)
    
    # 测试数据获取
    for i in range(5):
        data = connector.fetch_data()
        print(f"获取到数据: {json.dumps(data, ensure_ascii=False, indent=2)}")
        time.sleep(1)
    
    # 测试指令发送
    result = connector.send_command("SET_ANGLE:30")
    print(f"指令结果: {result}")
